/**
 * @author xuyunzhou
 */
define(['app',
    'jquery',
    'angular',
    'webuploader',
    'ieVersion',
    'caret',
    'directives/InfiniteScroll',
    'services/TipsService',
    'services/EmotionService',
    'filters/byte'
], function(app, $, angular, WebUploader, ieVersion) {

    'use strict';
	
	var deps = ['$timeout', '$http', 'TipsService', 'EmotionService'];
	
	function directive($timeout, $http, TipsService, EmotionService) {
		return {
			restrict : 'A',
			require: 'ngModel',
			scope : {
				text : '=ngModel',
				ctrlEnter : '&?',
                editorConfig : '=?',
                selectAtUserList : '=?'
			},
			templateUrl : 'views/common/editor/editor.html',
			replace : true,
			link : function($scope, element) {

				$scope.text = $scope.text || '';
                $scope.state = {};

                $scope.editor = element.find('[contenteditable]');
				$scope.editor.html($scope.text);

                updateConfig();
                $scope.$watch('editorConfig', updateConfig);

                function updateConfig() {
                    $scope.config = $.extend({
                        toolbar: {
                            atUser: false,
                            fontFormat: false,
                            emotions: false,
                            image: false,
                            attach: false
                        },
                        atUserLoader: angular.noop(),
                        emotions: [ 'goldElephantSmall', 'elephantSmall', 'normal' ],
                        emotionPublish: false,
                        pastePlain: true
                    }, $scope.editorConfig);

                    if (angular.isArray($scope.config.toolbar)) {
                        $scope.config.toolbar = {
                            atUser: $scope.config.toolbar.indexOf('atUser') !== -1,
                            fontFormat: $scope.config.toolbar.indexOf('fontFormat') !== -1,
                            emotions: $scope.config.toolbar.indexOf('emotions') !== -1,
                            image: $scope.config.toolbar.indexOf('image') !== -1,
                            attach: $scope.config.toolbar.indexOf('attach') !== -1
                        };
                    }

                    if (!$scope.mainBehaviousInited) {
                        initMainBehaviour($scope, $timeout);
                    }

                    if ($scope.config.toolbar.atUser && !$scope.atUserInited) {
                        initAtUser($scope, $timeout, element);
                    }

                    if ($scope.config.toolbar.fontFormat && !$scope.fontFormatInited) {
                        initFontFormat($scope, $timeout, element);
                    }

                    if ($scope.config.toolbar.emotions && $scope.config.emotions && $scope.config.emotions.length > 0 && !$scope.emotionsInited) {
                        initEmotions($scope, $timeout, element, EmotionService);
                    }

                    // 添加图片处理
                    if ($scope.config.toolbar.image && !$scope.imageInited) {
                        initImage($scope, $http, $timeout, element, TipsService);
                    }

                    // 添加附件处理
                    if ($scope.config.toolbar.attach && !$scope.attachInited) {
                        initAttach($scope, $timeout, element);
                    }
                }
			}
		};
	}

    var filterFns = [];
    var reverseFns = [];

    function getSelection($scope) {
        // 聚焦当前编辑区域，暂时解决一个页面多个富文本编辑器时，无法准确定位光标的问题
        $scope.editor.focus();
        var selection = document.getSelection();
        return selection;
    }

    function getRange(selection) {
        if (selection.rangeCount > 0) {
            return selection.getRangeAt(0);
        }
        return null;
    }

    function filter(text) {
        if (!text) {
            return text;
        }

        for (var i = 0, len = filterFns.length; i < len; i++) {
            text = filterFns[i](text);
        }
        return text;
    }

    function isFireFox(){
        return navigator.userAgent.indexOf('Firefox')>0;
    }

    function reverse(text) {
        if (!text) {
            return text;
        }

        for (var i = 0, len = reverseFns.length; i < len; i++) {
            text = reverseFns[i](text);
        }

        var reg = new RegExp('&nbsp;', 'g');
        return text.replace(reg,' ');
    }

    function wrap($scope, node) {
        var selection = getSelection($scope);
        var range = getRange(selection);

        var $end = $(range.endContainer);
        if ($end.is('span[contenteditable]') || $end.parent().is('span[contenteditable]')) {
            range.setStartAfter($end.closest('span[contenteditable]')[0]);
        }

        range.deleteContents();
        range.insertNode(node);
        range.setStartAfter(node);

        selection.removeAllRanges();
        selection.addRange(range);
    }

    function execCommand($scope, $timeout, command, text) {
        var selection = getSelection($scope);
        if (selection || text) {
            document.execCommand(command, false, text || selection.toString());

            $scope.isInterChangedTimeout = $timeout(function () {
                $scope.text = reverse($scope.editor.html());
            }, 0);
        }
    }

    function initMainBehaviour($scope, $timeout) {

        $scope.mainBehaviousInited = true;

        $scope.$watch('text', updateView);

        // 处理粘贴, 纯文本粘贴
        $scope.editor.on('paste', handlePaste);

        $scope.editor.on('keyup change', handleTextChange);

        $scope.editor.on('blur', updateModel);

        $scope.$bus.subscribe({
            channel: 'editor',
            topic: 'focus',
            callback: function(data) {
                $scope.editor.focus();

                if (data && data.moveToEnd) {
                    var selection = getSelection($scope);
                    selection.selectAllChildren($scope.editor[0]);
                    selection.collapseToEnd();
                }
            }
        });


        function updateView(newValue) {
            if($scope.isInterChangedTimeout) {
                delete $scope.isInterChangedTimeout;
            }
            /**用于在初始化编辑框时，将缓存的草稿文本刷新到页面;
             * 或者清空编辑框时;**/
            if ($scope.editor.html().length === 0 || (!newValue || newValue === '')) {
                $scope.editor.html(filter(newValue || ''));
            }
        }

        function handlePaste(event) {
            var clipboardData = event.originalEvent.clipboardData;

            if ($scope.config.pastePlain && hasPlainText(clipboardData)) {
                // 如果是要进行纯文本粘贴, 并且剪切板里面也确实有纯文本内容
                // 构造插入的节点
                var text = clipboardData.getData('text/plain');
                var textNode = document.createTextNode(text);

                wrap($scope, textNode);

                $scope.editor.focus();

                handleTextChange(event);
                return false;
            }

            // 如果没有纯文本, 则默认处理
            handleTextChange(event);
        }

        function hasPlainText(clipboardData) {
            var types = clipboardData.types;

            if (!types) {
                return false;
            }
            if (types.contains && types.contains('text/plain')) {
                // Firefox 下, 这个types 是一个类型, 有contains() / item() 这些方法
                return true;
            }
            // 在Chrome 里面, types 就只是一个数组.
            return types.indexOf && types.indexOf('text/plain') !== -1;
        }

        function handleTextChange(event) {
            $scope.isInterChangedTimeout = $timeout(function(){
                if (isCtrlEnter(event) && $scope.ctrlEnter) {
                    $scope.ctrlEnter();
                    if($scope.isInterChangedTimeout) {
                        delete $scope.isInterChangedTimeout;
                    }
                }

                if (isNativeCtrlEnter(event) && !isCtrlEnter(event)) {
                    // ctrl + enter 被修改过
                    if (ieVersion || isFireFox()) {
                        wrap($scope, document.createElement('br'));
                    } else {
                        execCommand($scope, $timeout, 'insertParagraph');
                    }
                }

                $scope.text = reverse($scope.editor.html());

                if ($scope.config.toolbar.atUser && $scope.config.atUserLoader) {
                    $scope.initAtUser();
                    $scope.refreshAtUserList();
                }
            });
        }

        function isCtrlEnter(event) {
            if ($scope.config.ctrlEnterEvent) {
                return $scope.config.ctrlEnterEvent(event);
            }
            return isNativeCtrlEnter(event);
        }

        function isNativeCtrlEnter(event) {
            return event.ctrlKey && event.keyCode === 13;
        }

        function updateModel(){
            $scope.isInterChangedTimeout = $timeout(function(){
                $scope.text = reverse($scope.editor.html());
                if($scope.isInterChangedTimeout) {
                    delete $scope.isInterChangedTimeout;
                }
            }, 0);
        }

    }

    function initAtUser($scope, $timeout, elem) {

        $scope.atUserInited = true;

        //用于存放@人员的数据
        $scope.atObj = {};
        $scope.atObj.flag = '@';

        $timeout(function findPanel() {
            $scope.atObj.atUserPanel = elem.find('.AtUserDiv');
        }, 0);

        //@人搜索时分页加载人员
        $scope.pageNo = 1;
        var pageSize = 12;

        /** 插入@并显示人员列表 **/
        $scope.insertAtMen = function(){
            $scope.editor.focus();
            var $insert_node = document.createTextNode('@');
            wrap($scope, $insert_node);
            $scope.isInterChangedTimeout = $timeout(function(){
                $scope.text = reverse($scope.editor.html());
            }, 0);

            $timeout(function(){
                at_catch_query();
            }, 0);
        };

        //获取@关键字
        $scope.initAtUser = function initAtUser(){
            at_catch_query();
        };

        function at_catch_query(){
            var max_name_len = '30',
                content = $scope.editor.text(),
                caret_pos = $scope.editor.caret('pos'),
                subtext = content.slice(0, caret_pos);
            var queryTxt = at_matcher(subtext);
            if (typeof queryTxt === 'string' && queryTxt.length <= max_name_len) {
                var start = caret_pos - queryTxt.length;
                var end = start + queryTxt.length;

                var selection = getSelection($scope);
                var range = getRange(selection);
                $scope.atObj.query = {
                    'text': queryTxt,
                    'head_pos': start,
                    'end_pos': end,
                    selection: selection,
                    range: range
                };
                $scope.pageNo = 1;
                $scope.AtUserList = [];
                loadUserData();
                showAtPanel();
            } else {
                $scope.atObj.atUserPanel.hide();
            }
        }

        //匹配@关键字
        function at_matcher(subtext){
            var match, regexp;
            var flag = $scope.atObj.flag;
            regexp = new RegExp(flag+ '([A-Za-z0-9_\u4e00-\u9fa5\\+\\-]*)$', 'gi');     /**匹配：大小写字母 数字 _ 汉字 + -**/
            match = regexp.exec(subtext);
            if (match) {
                return match[2] || match[1];
            } else {
                return null;
            }
        }

        //点击选择@人员时，加入列表
        $scope.addSelcteAtUserList = function(user){
            //如果已经有这个用户，就不再加入
            if($scope.selectAtUserList && $scope.selectAtUserList.length>0){
               for(var index in $scope.selectAtUserList){
                   var temp = $scope.selectAtUserList[index];
                   if(temp.userId == user.userId){
                       return;
                   }
               }
            }
            $scope.selectAtUserList = $scope.selectAtUserList || [];
            $scope.selectAtUserList.push(user);
        };

        //用户编辑内容时刷新已选择@人员列表，剔除已被用户删除的人员
        $scope.refreshAtUserList = function(){
            var html = $scope.editor.html();
            if($scope.selectAtUserList && $scope.selectAtUserList.length>0){
                for(var i=$scope.selectAtUserList.length-1;i>-1;i--){
                    var tempUser = $scope.selectAtUserList[i];
                    var userSpan = '<span contenteditable="false">@' + tempUser.userName +'&nbsp;</span>';
                    if(html.indexOf(userSpan)<0){
                        $scope.selectAtUserList.splice(i,1);
                    }
                }
            }
        };


        //构造插入的节点
        function getAtUserNode(user){
            if(isFireFox()){
                var $insert_node = $('<input type="button" class="edit-btn" disabled="disabled"/>');
                $insert_node.val('@' + user.userName);
            }else{
                var $insert_node = $('<span></span>');
                $insert_node.attr("contenteditable","false");
                $insert_node.html('@' + user.userName + "&nbsp;");
            }
            return $insert_node;
        }

        $scope.selectUser = function(user){

            var $insert_node = getAtUserNode(user);

            //插入节点
            var query = $scope.atObj.query;
            var selection = query.selection;
            var range = query.range;
            var pos = range.startOffset - (query.end_pos - query.head_pos) - $scope.atObj.flag.length;
            range.setStart(range.endContainer, Math.max(pos, 0));
            range.setEnd(range.endContainer, range.endOffset);

            range.deleteContents();
            range.insertNode($insert_node[0]);
            range.setStartAfter($insert_node[0]);
            range.collapse(false);
            selection.removeAllRanges();
            selection.addRange(range);

            $scope.addSelcteAtUserList(user);

            $scope.isInterChangedTimeout = $timeout(function(){
                $scope.text = reverse($scope.editor.html());
            });

            $scope.atObj.atUserPanel.hide();
        };

        //定位@User选择框的位置并显示
        function showAtPanel(){
            var offset = $scope.editor.caret('offset');
            if (offset) {
                var style;
                if ($scope.config.calcAtUserPanel) {
                    style = $scope.config.calcAtUserPanel(offset);
                } else {
                    style = {
                        left: offset.left,
                        top: offset.top + 25
                    };
                }
                $scope.atObj.atUserPanel.css(style);
                $scope.atObj.atUserPanel.show();
            }

        }


        /**用于外部调用，插入指定@的人**/
        $scope.$bus.subscribe({
            channel: 'editor.atMen',
            topic: 'insert',
            callback: function insertAtMen(user) {
                var selection = getSelection($scope);
                selection.selectAllChildren($scope.editor[0]);
                selection.collapseToEnd();
                var range = selection.getRangeAt(0);
                var $insert_node = getAtUserNode(user);
                range.insertNode($insert_node[0]);
                range.setStartAfter($insert_node[0]);
                range.collapse(false);
                selection.removeAllRanges();
                selection.addRange(range);

                $scope.addSelcteAtUserList(user);

                $scope.isInterChangedTimeout = $timeout(function(){
                    $scope.text = reverse($scope.editor.html());
                });
            }
        });

        //初始化加载控制
        $scope.load = $scope.load || {};
        $scope.AtUserList = [];

        $scope.scrollHandler = function () {
            if ($scope.load.loading) {
                return;
            }
            $scope.pageNo++;
            loadUserData();
        };

        function loadUserData(){
            $scope.load.loading = true;

            if(!$scope.config.atUserLoader){
                return;
            }

            $scope.config.atUserLoader($scope.atObj.query.text, $scope.pageNo, pageSize).success(function(data){
                for(var i=0;i<data.length;i++){
                    if(!isExist(data[i].userId)){
                        $scope.AtUserList.push(data[i]);
                    }
                }
                $scope.load.loading = false;
                if (data && data.length < pageSize) {
                    $scope.load.loading = true;
                }
            });

        }

        //判断要增加的人员是否已存在
        function isExist(userId){
            for(var i=0;i<$scope.AtUserList.length;i++){
                if($scope.AtUserList[i].userId == userId){
                    return true;
                }
            }
            return false;
        }

        function inputReverse(text) {
            //火狐下特殊处理，将Input转化为span保存到后台
            if(isFireFox()){
                var reg = new RegExp('<input value="(@[A-Za-z0-9_\u4e00-\u9fa5\\+\\-]*)" class="edit-btn" disabled="disabled" type="button">', 'g');
                text = text.replace(reg, '<span contenteditable="false">$1&nbsp;</span>');
            }
            return text;
        }

        function spanToInput(text){
            //火狐下特殊处理，将后台span转化为input
            if(isFireFox()){
                var reg = new RegExp('<span contenteditable="false">(@[A-Za-z0-9_\u4e00-\u9fa5\\+\\-]*)&nbsp;</span>', 'g');
                text = text.replace(reg, '<input value="$1" class="edit-btn" disabled="disabled" type="button">');
            }
            return text;
        }

        reverseFns.push(inputReverse);
        filterFns.push(spanToInput);
    }

    function initFontFormat($scope, $timeout, elem) {
        $scope.fontFormatInited = true;

        $scope.toolbar = {
            fontName :  [
                {value : 'SimSun', text : '宋体'},
                {value : 'NSimSun', text : '新宋体'},
                {value : 'FangSong_GB2312', text : '仿宋_GB2312'},
                {value : 'KaiTi_GB2312', text : '楷体_GB2312'},
                {value : 'SimHei', text : '黑体'},
                {value : 'Microsoft YaHei', text : '微软雅黑'},
                {value : 'Arial', text : 'Arial'},
                {value : 'Arial Black', text : 'Arial Black'},
                {value : 'Times New Roman', text : 'Times New Roman'},
                {value : 'Courier New', text : 'Courier New'},
                {value : 'Tahoma', text : 'Tahoma'},
                {value : 'Verdana', text : 'Verdana'}
            ]
        };

        var parents = elem.parents();
        $scope.showFontFormatBar = function showFontFormatBar(event){
            if (!$scope.state.isShowFontFormatBar) {
                $scope.state.isShowFontFormatBar = true;
            }
            event.stopPropagation();
        };
        $scope.hideFontFormatBar = function hideFontFormatBar(){
            if ($scope.state.isShowFontFormatBar) {
                $timeout(function() {
                    $scope.state.isShowFontFormatBar = false;
                }, 0);
            }
        };

        parents.on('click', $scope.hideFontFormatBar);
        // 销毁的时候要去掉这个点击事件, 不然内存不能释放了.
        $scope.$on('$destroy', function destroyEditor() {
            parents.off('click', $scope.hideFontFormatBar);
        });

        function doExecCommand(command, text) {
            execCommand($scope, $timeout, command, text);
        }

        // 设置选中文本为粗体
        $scope.bold = false;
        $scope.setBold = function() {
            doExecCommand('Bold');
            $scope.bold = !$scope.bold;
        };

        // 设置选中文本为斜体
        $scope.italic = false;
        $scope.setItalic = function() {
            doExecCommand('Italic');
            $scope.italic = !$scope.italic;
        };

        // 为选中文本设置下划线
        $scope.line = false;
        $scope.setUnderline = function() {
            doExecCommand('Underline');
            $scope.line = !$scope.line;
        };

        // 设置选中文本的字体
        $scope.setFontName = function(name, text,$event) {
            $scope.fontName = text;
            doExecCommand('FontName', name);
            var $dropdown = $($event.target).parents(".dropdown");
            $($dropdown[0]).removeClass("open");
        };

        // 设置数字型的项目列表
        $scope.setOrderedList = function() {
            doExecCommand('InsertOrderedList');
        };

        $scope.setUnorderedList = function() {
            doExecCommand('InsertUnorderedList');
        };
    }

    function initEmotions($scope, $timeout, elem, EmotionService) {
        $scope.emotionsInited = true;

        //用于存放表情框的数据
        $scope.emoObj = {};
        $scope.emoObj.emotionShow = false;
        $scope.emoObj.dafult = true;

        var parents = elem.parents();
        $scope.showEmotions = function showEmotions(event){
            if (!$scope.emoObj.emotionShow) {
                $scope.emoObj.emotionShow = true;
            }
            event.stopPropagation();
        };
        $scope.hideEmotions = function hideEmotions(){
            if ($scope.emoObj.emotionShow) {
                $timeout(function() {
                    $scope.emoObj.emotionShow = false;
                }, 0);
            }
        };

        parents.on('click', $scope.hideEmotions);
        // 销毁的时候要去掉这个点击事件, 不然内存不能释放了.
        $scope.$on('$destroy', function destroyEditor() {
            parents.off('click', $scope.hideEmotions);
        });

        // 根据数值转换成长度为该数值，值为从0到该数值-1的数组
        // 主要用于控制表情的行列以及页码的显示
        $scope.range = function (num) {
            var list = [];
            for (var i = 0; i < num; i++) {
                list.push(i);
            }

            return list;
        };

        $scope.getConfig = function getConfig(type) {
            $scope.emotionConfig = EmotionService.getConfig(type);

            var config = $scope.emotionConfig;
            config.itemCountPerPage = config.rowsPerPage * config.columnsPerRow;
            $scope.pages = Math.ceil(config.total / config.itemCountPerPage);

            $scope.pageIndex = 1;
        };
        $scope.getConfig($scope.config.emotions[0]);

        /**用于表情页，根据所在行与所在列，返回该位置值
         如第2行第1列，位置值为10
         社区logo表情列重用这个获取 index值的方法，不同点是社区logo表情的位置值从500开始计数；
         **/
        $scope.getItemIndex = function (rowIndex, columnIndex) {
            var config = $scope.emotionConfig;
            return config.itemCountPerPage * ($scope.pageIndex - 1) + (rowIndex * config.columnsPerRow + columnIndex);
        };

        // 插入表情
        $scope.insertEmotion = function (row, column) {
            var config = $scope.emotionConfig;

            if (config.publish && $scope.config.emotionPublish) {
                var itemIndex = $scope.getItemIndex(row, column);
                $scope.$bus.publish({
                    channel: 'editor',
                    topic: 'emotion',
                    data: {
                        text: config.emotions[itemIndex],
                        image: EmotionService.getEmotionImg(config, itemIndex),
                        index: itemIndex,
                        config: config
                    }
                });
            } else {
                var emotion = getEmotionImage(row, column);
                doInsertEmotion(emotion);
            }

            $scope.emoObj.emotionShow = false;
        };

        function doInsertEmotion(emotion) {
            var image = document.createElement('img');

            image.src = emotion;
            wrap($scope, image);
            $scope.isInterChangedTimeout = $timeout(function () {
                $scope.text = reverse($scope.editor.html());
            }, 0);
        }

        function getEmotionImage(row, column) {
            var itemIndex = $scope.getItemIndex(row, column);
            return EmotionService.getEmotionImg($scope.emotionConfig, itemIndex);
        }

        $scope.getEmotionImage = getEmotionImage;

        $scope.setPageIndex = function (index, event) {
            $scope.pageIndex = index;
            event.stopPropagation();
        };

        function emotionFilter(text) {
            return EmotionService.resolve(text);
        }

        function emotionReverse(text) {
            for (var i = 0, len = $scope.config.emotions.length; i < len; i++) {
                var type = $scope.config.emotions[i];
                text = EmotionService.reverse(type, text);
            }
            return text;
        }
        filterFns.push(emotionFilter);
        reverseFns.push(emotionReverse);
    }

    function initImage($scope, $http, $timeout, elem, TipsService) {
        $scope.imageInited = true;

        var imageRegex = /(\.|\/)(gif|jpe?g|png|bmp)$/i;

        $timeout(function () {
            elem.find('.js-img-input').on('change', function () {
                insertImages(this.files);
                this.value = '';
                this.files.length = 0;
            });
        }, 0);

        $scope.editor.on('dragenter dragover', function drag() {
            return false;
        });
        $scope.editor.on('drop', $scope.dropIt);

        /** 拖放图片 **/
        $scope.dropIt = function (e) {
            insertImages(e.dataTransfer.files);
            e.stopPropagation();
            e.preventDefault();
        };

        /** 插入图片**/
        function insertImages(images) {
            angular.forEach(images, insertSingleImg);
        }

        function insertSingleImg(file) {
            if (!(imageRegex.test(file.type) || imageRegex.test(file.name))) {
                TipsService.show('请选择图片');
                return;
            }

            upload(file).success(function (attachsVo) {
                var $image = $(document.createElement('img'));
                $image.attr('src', 'restful/fileUploadController/showPic/' + attachsVo.attachsId + '?picType=2');
                $image.attr('class', 'imgViewAble');
                $image.attr('picId', attachsVo.attachsId);
                wrap($scope, $image[0]);
                $scope.isInterChangedTimeout = $timeout(function () {
                    $scope.text = reverse($scope.editor.html());
                }, 0);
            });
        }

        function upload(file) {
            var fd = new FormData();
            fd.append('file', file);
            return $http.post('restful/fileUploadController/fileUploadReturn', fd, {
                transformRequest: angular.identity,
                headers: {
                    'Content-Type': undefined
                }
            });
        }

        function imageFilter(text) {
            var reg = new RegExp('\\[([a-z0-9]{24})\\]', 'g');
            var replacement = '<img src="restful/fileUploadController/showPic/$1?picType=2" class="imgViewAble" picid="$1">';
            return text.replace(reg, replacement);
        }

        function imageReverse(text) {
            //处理图片
            var reg = new RegExp('<img.+?picid="([a-z0-9]+)".*?>', 'g');
            return text.replace(reg, '[$1]');
        }
        filterFns.push(imageFilter);
        reverseFns.push(imageReverse);
    }

    function initAttach($scope, $timeout, elem) {
        $scope.attachInited = true;

        var uploader = WebUploader.create({
            // 文件接收服务端。
            server: 'restful/fileUploadController/fileUploadReturn',
            // 选择文件的按钮。可选。
            // 内部根据当前运行是创建，可能是input元素，也可能是flash.
            thumb: false,
            compress: false
        });

        var attachIds = [];

        $scope.localFiles = [];
        $scope.progressStylies = {};

        $timeout(function() {
            elem.find('.js-attach-input').on('change', function() {
                uploader.addFiles(this.files);
                this.value = '';
                this.files.length = 0;
            });
        }, 0);

        $scope.remove = function remove(file, index) {
            $scope.localFiles.splice(index, 1);
            $scope.progressStylies[file.id] = null;
            uploader.removeFile(file, true);
        };

        // 当有文件被添加进队列的时候
        uploader.on('fileQueued', function fileQueued(file) {
            $scope.localFiles.push(file);
            $scope.$bus.publish({
                channel: 'upload.editor.attach',
                topic: 'fileQueued',
                data: file
            });
            $scope.$apply();
        });
        uploader.on('filesQueued', function fileQueued(files) {
            $scope.$bus.publish({
                channel: 'upload.editor.attach',
                topic: 'filesQueued',
                data: files
            });
            $scope.$apply();
        });

        // 当有文件被移出队列的时候
        uploader.on('fileDequeued', function fileDequeued(file) {
            $scope.$bus.publish({
                channel: 'upload.editor.attach',
                topic: 'fileDequeued',
                data: file
            });
        });

        uploader.on('error', function error(type) {
            $scope.$bus.publish({
                channel: 'upload.editor.attach',
                topic: 'error',
                data: type
            });
        });

        // 文件上传过程中创建进度条实时显示。
        uploader.on('uploadProgress', function uploadProgress(file, percentage) {
            $scope.progressStylies[file.id] = $scope.progressStylies[file.id] || {};
            $scope.progressStylies[file.id].width = percentage * 100 + '%';
            $scope.$apply();
        });

        uploader.on('uploadSuccess', function uploadSuccess(file, response) {
            $scope.progressStylies[file.id].width = '100%';
            attachIds.push(response.attachsId);
            $scope.$bus.publish({
                channel: 'upload.editor.attach',
                topic: 'uploadSuccess',
                data: {
                    file: file,
                    response: response
                }
            });
            $scope.$apply();
        });

        uploader.on('uploadError', function uploadError(file, reason) {
            $scope.progressStylies[file.id].width = '0%';
            $scope.$bus.publish({
                channel: 'upload.editor.attach',
                topic: 'uploadError',
                data: {
                    file: file,
                    reason: reason
                }
            });
            $scope.$apply();
        });

        uploader.on('uploadFinished', function uploadFinished() {
            $scope.$bus.publish({
                channel: 'upload.editor.attach',
                topic: 'uploadFinished',
                data: {
                    attachIds: attachIds
                }
            });
        });

        $scope.$bus.subscribe({
            channel: 'upload.editor.attach',
            topic: 'start',
            callback: function startUpload() {
                uploader.upload();
            }
        });

        $scope.$bus.subscribe({
            channel: 'upload.editor.attach',
            topic: 'stop',
            callback: function stopUpload() {
                uploader.stop();
            }
        });

        $scope.$bus.subscribe({
            channel: 'upload.editor.attach',
            topic: 'reset',
            callback: function resetUpload() {
                for (var i = $scope.localFiles.length - 1; i >= 0; i--) {
                    $scope.remove($scope.localFiles[i], i);
                }
            }
        });

        return uploader;
    }

	directive.$inject = deps;
	app.lazy.directive('fcEditor', directive);
});